<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    /* 将页面中所有的默认的内边距,外边距设置为0 */
    * {
      padding: 0px;
      margin: 0px;
    }
    /* 再把列表中图片间隔的空白去除 */
    img {
      vertical-align: top;
    }
    /* ul中 列表样式去除 */
    ul {
      list-style: none;
    }
    .outer {
      width: 640px;
      height: 390px;
      /* 让其上下外边距为100 左右自动居中 */
      margin: 100px auto;
      /* 开启一个相对定位,让其内的元素能定位到outer内的位置 */
      position: relative;
    }
    .img-list {
      height: 390px;
    }
    .img-list li {
      position: absolute;
      /* 透明度 */
      opacity: 0;
      transition: opacity 1s;
    }

    li.cruuent {
      z-index: 1;
      opacity: 1;
    }
    /* 设置两个箭头的样式 */
    .prev-next a {
      font-size: 60px;
      color: #fff;
      /*加粗字体 */
      font-weight: bold;
      /* 字体的下划线等等特效 */
      text-decoration: none;
      /* 开启绝对定位来定位两个箭头的位置 */
      position: absolute;
      top: 0px;
      bottom: 0px;
      /* 居中 */
      margin: auto;
      /* 调制图层优先级 */
      z-index: 2;
      opacity: 0.5;
      /* 透明度 */
      /* 当开启绝对定位的时候,你把margin设置为auto height设置为0 的时候 auto跟0是一样的 设置一个跟文字一样的高度 */
      height: 60px;
    }
    .prev-next a:hover {
      /*让其在鼠标移动到上面去的时候增加透明度 */
      opacity: 1;
    }
    #prev {
      left: 0px;
    }
    #next {
      right: 0px;
    }
    /* 设置导航栏的样式 */
    .dot {
      position: absolute;
      display: flex;
      justify-content: center;
      z-index: 3;
      left: 0;
      right: 0;
      bottom: 5px;
      margin: auto;
    }

    .dot a {
      width: 20px;
      height: 20px;
      margin: 5px;
      /* 设置圆形 */
      border-radius: 50%;
      background-color: #fff;
      opacity: 0.5;
    }

    .dot a:hover,
    .active {
      opacity: 1;
    }
  </style>
  <body>
    <div class="outer">
      <ul class="img-list">
        <li class="cruuent">
          <a href="#">
            <img src="/JavaScript/10.DOM/images/1.png" alt="" />
          </a>
        </li>
        <li>
          <a href="#">
            <img src="/JavaScript/10.DOM/images/2.png" alt="" />
          </a>
        </li>
        <li>
          <a href="#">
            <img src="/JavaScript/10.DOM/images/3.png" alt="" />
          </a>
        </li>
        <li>
          <a href="#">
            <img src="/JavaScript/10.DOM/images/4.png" alt="" />
          </a>
        </li>
        <li>
          <a href="#">
            <img src="/JavaScript/10.DOM/images/5.png" alt="" />
          </a>
        </li>
      </ul>
      <!-- 设置两个按钮,实现上一张下一张的效果 -->
      <div class="prev-next">
        <a href="javascript:;" id="prev">←</a>
        <a href="javascript:;" id="next">→</a>
      </div>
      <!-- 设置5个小点,小点的作用是点哪个点,就切换到哪个相应的li的索引,然后切换图片,同时,没有被点击的时候,也会随着图片的索引变化而变化  -->
      <div class="dot">
        <a class="active" href="javascript:;"></a>
        <a href="javascript:;"></a>
        <a href="javascript:;"></a>
        <a href="javascript:;"></a>
        <a href="javascript:;"></a>
      </div>
    </div>
    <script>
      // 获取5个小点，然后获取document的单击事件，并且使用event.target 获取被相应的小点，操作事件，获取其被响应的小点在所有小点中的索引。对其进行删除添加，再操作相应的图片的索引
      const dotArr = [...document.querySelectorAll('.dot a')];
      const imgArr = [...document.querySelectorAll('ul.img-list > li')];
      document.addEventListener('click', (event) => {
        // 获取dotA的被响应的小点所在的所有小点数组中的索引
        const index = dotArr.indexOf(event.target);
        if (index !== -1) {
          // 实现切换图片的功能\
          // 获取class属性的a，然后删除

          changeImg(index);
        }
      });

      /*
                         之前那个轮播图因为是利用切换image来实现的,所以会导致网页加载的时候,第一次点的时候需要一次一次加载,这样子会
                         导致用户的体验较差
                         可以直接一次性把图片全部加载完,然后再一张一张的去进行切换,这样子全部加载,会导致页面被撑开了,而且也是全部图片都看到的
                         我们希望实现的是一张一张的轮播图
                         第一步是开启定位,把所有的图片移除文档流,让他不占用空间,之后就是设置高度,让图片的高度都设为一张
                         然后我们给第一张图片设置一个class或者id再设置样式z-index,设置优先级,让第一张图片优先显示
                         那么在JS中的操作,就是将第一个的class直接移到下一个 去.这样就能实现图片的轮换了.

             */

      /*

             简化代码
             实现上下页的简化,
             第二实现定时器的鼠标移入移出的开关功能,并且利用函数闭包,让其内部变量不被其他函数影响!
             */

      /* let timer;
           function autoTimer() {
             timer = setTimeout(
               (auto = () => {
                 //获取class为current的元素
                 const cruuent = document.querySelector('ul > li.cruuent');
                 // 获取下一个兄弟元素和li的第一个元素,防止出现null 
                 const nextCruuent = cruuent.nextElementSibling || document.querySelector('.img-list li');
                 cruuent.classList.remove('cruuent');
                 nextCruuent.classList.add('cruuent');
                 // 添加删除
                 timer = setTimeout(auto, 2000);
               }),
               2000
             );
           }
           autoTimer();

          */
      const toggleChange = (() => {
        let timer = null;
        return () => {
          if (timer === null) {
            timer = setTimeout(
              (auto = () => {
                changeImg('next');
                timer = setTimeout(auto, 2000);
              }),
              2000
            );
          } else {
            clearTimeout(timer);
            timer = null;
          }
        };
      })();
      toggleChange();

      /* 
          获取outer,完成移出移入的效果
        */
      const outer = document.getElementsByClassName('outer')[0];
      //当鼠标移入
      outer.onmouseenter = () => {
        toggleChange();
      };
      // 当鼠标移出
      outer.onmouseleave = () => {
        toggleChange();
      };

      // 实现按钮上下张的功能
      // 先获取元素,然后操作元素的onclick属性,也是同样的删除元素,给予元素class属性
      // 完善规则,如果上一张是第一个li所以导致前面没有元素了使用或条件
      const prev = document.getElementById('prev');
      const next = document.getElementById('next');
      prev.onclick = () => {
        changeImg('prev');
      };
      next.onclick = () => {
        changeImg('next');
      };
      // 相同点是都需要通过当前的class拥有者来获取其上下,所以这个肯定是不变的,要放在第一
      const changeImg = (dir) => {
        // 声明一个变量来存储其class的上下两个不同的属性
        const cruuent = document.querySelector('ul > li.cruuent');
        let NP;
        if (dir === 'next') {
          NP = cruuent.nextElementSibling || imgArr[0];
        } else if (dir === 'prev') {
          NP = cruuent.previousElementSibling || imgArr.at(-1);
        } else if (typeof dir === 'number') {
          NP = imgArr[dir];
        }
        // 获取显示的图片的索引用来操作小点，对照小点的索引，来操作小点。
        // index =  imgArr中包含NP内容的值的索引，比如我点的是第二个按钮，这个时候，出发changeImge函数，获取到了被点击的小点的索引，利用索引，NP就=了第二个图片的li，
        // 再去利用NP的索引，去声明一个index，用imgarr数组的indexof方法查找数组中拥有imgArr[1]这个li相对的索引，给予赋值index。最后再去操作给小点添加calss属性
        const index = imgArr.indexOf(NP);
        // 稳定不变的切换显示状态
        cruuent.classList.remove('cruuent');
        NP.classList.add('cruuent');
        // clearTimeout(timer);
        // timer = setTimeout(autoTimer);

        const currentActive = document.querySelector('.active');
        currentActive.classList.remove('active');

        // 给被响应的小点添加上class属性
        dotArr[index].classList.add('active');
      };

      /*       prev.addEventListener('click', () => {
             const cruuent = document.querySelector('ul > li.cruuent');
             const prevcruuent = cruuent.previousElementSibling || document.querySelector('ul.img-list').lastElementChild;
             cruuent.classList.remove('cruuent');
             prevcruuent.classList.add('cruuent');
             clearTimeout(timer);
             // 这个执行是直接塞一个我的计时器函数,但是是在2000后,我2000才塞函数,进入堆栈运行,里面的代码也是2000毫秒,再等2000,导致点了一次以后,第一次响应切图片
             timer = setTimeout(autoTimer);
           });
      */
      /*       next.addEventListener('click', () => {
             const cruuent = document.querySelector('ul > li.cruuent');
             const prevcruuent = cruuent.nextElementSibling || document.querySelector('ul.img-list').firstElementChild;
             cruuent.classList.remove('cruuent');
             prevcruuent.classList.add('cruuent');
             clearTimeout(timer);
             timer = setTimeout(autoTimer);
           });
      */
    </script>
  </body>
</html>
